package org.tgcloud.group.web.controller.manager;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import io.swagger.annotations.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.*;
import org.tgcloud.group.core.APPResultMessage;
import org.tgcloud.group.core.BeanUtil;
import org.tgcloud.group.core.DateUtil;
import org.tgcloud.group.core.StringUtil;
import org.tgcloud.group.core.custom.Permissions;
import org.tgcloud.group.core.session.Session;
import org.tgcloud.group.service.manager.MediumCountManagerService;
import org.tgcloud.group.web.controller.dto.home.HomeProjectMsg;
import org.tgcloud.group.web.controller.dto.medium.MediumCountExportDTO;
import org.tgcloud.group.web.controller.dto.medium.MediumOfflineCountDTO;

import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: zhy
 * @create: 2023-12-18 09:24
 * @description: 媒体统计管理相关接口
 */
@Api(tags = "媒体统计管理相关接口")
@RestController
@RequestMapping("/manager/pc/user")
@EnableAutoConfiguration
public class MediumCountManagerController extends ManageAPPBaseController{

    @Autowired
    private MediumCountManagerService mediumCountManagerService;



    @Permissions("mediumCount:view")
    @ApiOperation(value = "媒体统计列表-项目")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "string")
    })
    @ResponseBody
    @RequestMapping(value = "/getMediumCountList", method = RequestMethod.POST)
    public APPResultMessage getMediumCountList(@ModelAttribute("session") Session session,
                                                @RequestParam(required = false) Integer pageNum,
                                                @RequestParam(required = false) Integer pageSize,
                                                @RequestParam(required = false) String projectIds,
                                               @RequestParam(required = false) Long startTime,
                                               @RequestParam(required = false) Long endTime){
        return mediumCountManagerService.getMediumCountList(pageNum, pageSize, projectIds,
                startTime == null ? null : new Date(startTime), endTime == null? null : new Date(endTime));
    }


    @Permissions("mediumCount:view")
    @ApiOperation(value = "媒体统计列表-项目列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "string")
    })
    @ResponseBody
    @RequestMapping(value = "/getProjectListFromMediumCount", method = RequestMethod.POST)
    public APPResultMessage getProjectListFromMediumCount(@ModelAttribute("session") Session session){
        return mediumCountManagerService.getProjectListFromMediumCount();
    }



    /* 导出 */
    @ApiOperation(value = "导出媒体统计列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "token", required = true, dataType = "string"),
    })
    @ResponseBody
    @PostMapping(value = "/doExportMediumCount")
    public void doExportMediumCount(HttpServletResponse response,
                              @RequestParam(required = false) Integer pageNum,
                              @RequestParam(required = false) Integer pageSize,
                              @RequestParam(required = false) String projectIds,
                              @RequestParam(required = false) Long startTime,
                              @RequestParam(required = false) Long endTime) throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/octet-stream;charset=UTF-8");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String excelName = "媒体统计-" + dateFormat.format(new Date());
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(excelName, "UTF-8") + ".xls");
        response.addHeader("filename", URLEncoder.encode(excelName, "UTF-8"));

        // 获取excel显示第一行的字段名
        List<String> headers = Lists.newArrayList();
        MediumCountExportDTO msg = new MediumCountExportDTO();
        Field[] declaredFields = msg.getClass().getDeclaredFields();
        for (Field field : declaredFields){
            field.setAccessible(true);
            String value = field.getAnnotation(ApiModelProperty.class).value();
            boolean required = field.getAnnotation(ApiModelProperty.class).required();
            if (required){
                headers.add(value);
            }else {
                if (startTime != null && endTime != null){
                    headers.add(value);
                }
            }
        }


        try {
            OutputStream out = response.getOutputStream();
            APPResultMessage<Object, MediumOfflineCountDTO> successMessage = mediumCountManagerService.getMediumCountList(pageNum, pageSize, projectIds,
                    startTime == null ? null : new Date(startTime), endTime == null? null : new Date(endTime));
            getExportListExcel(excelName, headers, successMessage, out, startTime, endTime);
            out.close();
            System.out.println("excel导出成功！");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void getExportListExcel(String title, List<String> headers,
                                          APPResultMessage<Object, MediumOfflineCountDTO> message, OutputStream out,
                                          Long startTime, Long endTime) throws Exception{
        //声明一个工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        //生成一个表格
        HSSFSheet sheet = workbook.createSheet(title);
        //设置表格默认列宽度为15个字符
        sheet.setDefaultColumnWidth(20);
        //生成一个样式，用来设置标题样式
        HSSFCellStyle style = workbook.createCellStyle();
        //设置这些样式
        style.setFillForegroundColor(HSSFColor.HSSFColorPredefined.SKY_BLUE.getIndex());
        //生成一个字体
        HSSFFont font = workbook.createFont();
        font.setColor(HSSFColor.HSSFColorPredefined.VIOLET.getIndex());
        //把字体应用到当前的样式
        style.setFont(font);
        // 生成并设置另一个样式,用于设置内容样式
        HSSFCellStyle style2 = workbook.createCellStyle();
        style2.setFillForegroundColor(HSSFColor.HSSFColorPredefined.LIGHT_YELLOW.getIndex());
        // 生成另一个字体
        HSSFFont font2 = workbook.createFont();
        // 把字体应用到当前的样式
        style2.setFont(font2);
        //产生表格标题行
        HSSFRow row = sheet.createRow(0);
        for (int i = 0; i < headers.size(); i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellStyle(style);
            HSSFRichTextString text = new HSSFRichTextString(headers.get(i));
            cell.setCellValue(text);
        }

        List<MediumOfflineCountDTO> dtoList = message.getResult().getList();
        List<MediumCountExportDTO> list = new ArrayList<>();
        for (MediumOfflineCountDTO dto : dtoList){
            MediumCountExportDTO exportDTO = new MediumCountExportDTO();
            BeanUtils.copyProperties(dto, exportDTO);
            list.add(exportDTO);
        }
        if (!BeanUtil.isNullList(list)) {
            for (int i = 0; i < list.size(); i++) {
                row = sheet.createRow(i + 1);
                int j = 0;
                MediumCountExportDTO dto = (MediumCountExportDTO) list.get(i);
                // 获取excel里对应的值
                Field[] declaredFields = dto.getClass().getDeclaredFields();
                for (Field field : declaredFields){
                    field.setAccessible(true);
                    Object o = field.get(dto);
                    HSSFCell cell = null;
                    boolean required = field.getAnnotation(ApiModelProperty.class).required();
                    if (required){
                        cell = row.createCell(j++);
                    }else {
                        if (startTime!= null && endTime!= null){
                            cell = row.createCell(j++);
                        }
                    }
                    if (cell != null){
                        if (o == null){
                            cell.setCellValue("");
                        }else {
                            if (o instanceof Date){
                                Date date = new Date(((Date) o).getTime());
                                cell.setCellValue(DateUtil.getStrDate(date));
                            }else if (o instanceof BigDecimal){
                                CellStyle cellStyle = workbook.createCellStyle();
                                DataFormat dataFormat = workbook.createDataFormat();  //创建一个单元格数据格式
                                cellStyle.setDataFormat(dataFormat.getFormat("#,##0.00"));  //设置数据格式为数字
                                cell.setCellStyle(cellStyle);
                                if (JSON.toJSONString(o).equals("0E-8")){
                                    cell.setCellValue(0);
                                }else if (JSON.toJSONString(o).equals("0E-24")){
                                    cell.setCellValue(0);
                                }else {
                                    cell.setCellValue(((BigDecimal) o).doubleValue());
                                }
                            }else {
                                cell.setCellValue(o.toString());
                            }

                        }
                    }
                }

            }
        }

        try {
            workbook.write(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



}
